/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.branchstores.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.BranchPurchaseState;
import com.qinyeit.serviceapp.entity.enums.BranchPurchaseType;
import com.qinyeit.serviceapp.entity.enums.StoreOutState;
import com.qinyeit.serviceapp.entity.enums.StoreOutType;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.branchstores.BranchPurchaseOrderRepository;
import com.qinyeit.serviceapp.service.branchs.BranchDataServiceImpl;
import com.qinyeit.serviceapp.service.branchs.BranchOrderServiceImpl;
import com.qinyeit.serviceapp.service.branchstores.BranchPurchaseOrderDetailService;
import com.qinyeit.serviceapp.service.branchstores.BranchPurchaseOrderService;
import com.qinyeit.serviceapp.service.branchstores.BranchSupplierService;
import com.qinyeit.serviceapp.service.materials.MaterialService;
import com.qinyeit.serviceapp.service.materials.PurchaseSpecService;
import com.qinyeit.serviceapp.service.organization.BranchService;
import com.qinyeit.serviceapp.service.stores.StockService;
import com.qinyeit.serviceapp.service.stores.StoreOutOrderDetailService;
import com.qinyeit.serviceapp.service.stores.StoreOutOrderService;
import com.qinyeit.serviceapp.service.stores.WarehouseService;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.service.BaseService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparingLong;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/** 
 * ClassName: BranchPurchaseOrderServiceImpl <br/> 
 * Function: 门店采购订单 业务实现 <br/> 
 * date: 2018-11-29 17:12:44 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class BranchPurchaseOrderServiceImpl extends BaseService<BranchPurchaseOrder, Long> implements BranchPurchaseOrderService {


	@Autowired
	private BranchPurchaseOrderRepository branchPurchaseOrderRepository;
	@Autowired
	private BranchPurchaseOrderDetailService branchPurchaseOrderDetailService;
	@Autowired
	private StoreOutOrderService storeOutOrderService;
	@Autowired
	private StockService stockService;
	@Autowired
	private WarehouseService warehouseService;
	@Autowired
	private StoreOutOrderDetailService storeOutOrderDetailService;
	@Autowired
	private BranchOrderServiceImpl branchOrderService;
	@Autowired
	private BranchService branchService;
	@Autowired
	private MaterialService materialService;
	@Autowired
	private BranchDataServiceImpl branchDataService;


	@Override
	public void saveData(JSONObject data, Long merchantGroupId, String operator) {
		JSONObject orderData = data.getJSONObject("purchaseOrder");
		JSONArray detailData = data.getJSONArray("details");
		int type = data.getInteger("type");
		if(StringUtils.isBlank(orderData.getString("branchId")) || StringUtils.isBlank(orderData.getString("branchName"))){
			throw new BusinessRunTimeException("请选择直赔门店",1001);
		}
		if(CollectionUtils.isEmpty(detailData)){
			throw new BusinessRunTimeException("请选择物料明细",10002);
		}

		Long id = orderData.getLong("id");
		BranchPurchaseOrder order = null;
		if(id==null){
			order = new BranchPurchaseOrder();
			order.setNo(LocalUtils.getOrderNo());
		}else {
			order = this.findById(id);
			//删除明细订单
			branchPurchaseOrderRepository.deleteDetail(id);
		}
		if (type==1){
			//保存
			order.setState(BranchPurchaseState.NOAUDIT);
			order.setPurchaseTime(DateUtils.date());
			order.setPurchaser(operator);
		}else if (type==2){
			//审核
			order.setState(BranchPurchaseState.AUDIT);
			order.setChecker(operator);
			order.setCheckTime(DateUtils.date());
			if(StringUtils.isBlank(order.getPurchaser())){
				order.setPurchaser(operator);
				order.setPurchaseTime(DateUtils.date());
			}
		}else if(type==3){ //发货
			order.setSender(operator);
			order.setSendTime(DateUtils.date());
			order.setState(BranchPurchaseState.DELIVERED);
		}else if (type==4){//已完成
			order.setAcceptTime(DateUtils.date());
			order.setState(BranchPurchaseState.COMPLETED);
			//供应商 / 仓库 单店版发送消息在保存数据
		}
		order.setRemark(orderData.getString("remark"));
		order.setAddress(orderData.getString("address"));
		order.setBranchId(orderData.getLong("branchId"));
		order.setBranchName(orderData.getString("branchName"));
		order.setType(BranchPurchaseType.valueOf(orderData.getString("type")));
		order.setMerchantGroupId(merchantGroupId);
		order.setCreateAt(DateUtils.date());
		//获取单店的供应商
		Map<String,Object> supplierData = branchDataService.getBranchSupplier(orderData.getLong("branchId"));
		if(MapUtils.isNotEmpty(supplierData) && (order.getSupplierId()==null || StringUtils.isBlank(order.getSupplierName()))){
			order.setSupplierId(Long.valueOf(supplierData.get("id").toString()));
			order.setSupplierName(supplierData.get("name").toString());
		}
		order = this.update(order);
		JSONObject item ;
		BranchPurchaseOrderDetail detail = null;
		double amount = 0;
		double sumAmount = 0;
		List<BranchPurchaseOrderDetail> detailList = Lists.newArrayList();
		for (int i = 0; i < detailData.size(); i++) {
			amount = 0;
			item = detailData.getJSONObject(i);
			detail = new BranchPurchaseOrderDetail();
			detail.setMerchantGroupId(merchantGroupId);
			detail.setNo(item.getString("no"));
			detail.setName(item.getString("name"));
			detail.setUuid(item.getString("uuid"));
			detail.setOrder(order);
			detail.setGroupRemark(item.getString("groupRemark"));
			detail.setMaterialSpec(item.getString("materialSpec"));
			detail.setSpecId(item.getLong("specId"));
			detail.setPurchaseSpec(item.getString("purchaseSpec"));
			detail.setStockUnit(item.getString("stockUnit"));
			detail.setPurchaseUnit(item.getString("purchaseUnit"));
			detail.setPurchaseCount(item.getDouble("purchaseCount"));
			detail.setPurchasePrice(item.getDouble("purchasePrice"));
			detail.setBranchRemark(item.getString("branchRemark"));
			if(type==1 || type==2){
				amount = detail.getPurchaseCount()*detail.getPurchasePrice();
			}else if (type==3){ //确认发货
				detail.setSendCount(item.getDouble("sendCount"));
				detail.setSendPrice(item.getDouble("sendPrice"));
				detail.setStockId(item.getLong("stockId"));
				detail.setStockName(item.getString("stockName"));
				amount = detail.getSendCount()*detail.getSendPrice();
			}else if(type==4){ //已完成
				detail.setAcceptCount(item.getDouble("acceptCount"));
				detail.setAcceptPrice(item.getDouble("acceptPrice"));
			}
			detail = branchPurchaseOrderDetailService.save(detail);
			detailList.add(detail);
			sumAmount = CompuUtils.add(sumAmount,amount);
		}
		order.setAmount(sumAmount);
		order = this.update(order);

		if(order.getState()==BranchPurchaseState.DELIVERED){
			//减去库存 //出库单
			this.saveStoreOutOrder(order,detailList);
		}
		//保存门店的直配单
		if (order.getType()==BranchPurchaseType.ZHIPEI && order.getState()==BranchPurchaseState.AUDIT){
			branchOrderService.saveBranchPurchaseOrders(order,detailList);
		}else if (order.getState()==BranchPurchaseState.DELIVERED){
			//修改单店订单为待收货确认
			branchOrderService.saveBranchPurchaseOrders(order,detailList);
		}

	}

	@Override
	public void updateOrderState(Long id,Long merchantGroupId) {
		Map<String,Object> orderData = branchOrderService.getOrderData(id);
		List<Map<String,Object>> detailData = branchOrderService.getOrderDetailData(id);
//		修改订单状态为 已完成
		Searchable searchable = Searchable.newSearchable();
		searchable.addSearchParam("deleted_eq",false);
		searchable.addSearchParam("no_eq",orderData.get("no"));
		BranchPurchaseOrder order = this.findOne(searchable);
		if (order==null){
			return;
		}
		order.setState(BranchPurchaseState.COMPLETED);
		order.setAcceptTime(DateUtils.parse(orderData.get("accept_time").toString()));
		order.setWarehouseName(orderData.get("warehouse_name").toString());
		order = this.update(order);
		//修改订单明细
		searchable = Searchable.newSearchable();
		searchable.addSearchParam("order.id_eq",order.getId());
		searchable.addSearchParam("deleted_eq",false);
		searchable.addSort(Sort.Direction.ASC,"id");
		List<BranchPurchaseOrderDetail> detailList = branchPurchaseOrderDetailService.findWithSort(searchable);

		if (CollectionUtils.isEmpty(detailList) || CollectionUtils.isEmpty(detailData)){
			throw new BusinessRunTimeException("订单明细为空",10001);
		}
		if (detailList.size()!=detailData.size()){
			throw new BusinessRunTimeException("数据出错",10002);
		}

		QyMap map ;
		BranchPurchaseOrderDetail detail = null;
		for (int i = 0; i < detailList.size(); i++) {
			map = QyMap.WRAP(detailData.get(i));
			detail = detailList.get(i);
			detail.setAcceptCount(map.getDouble("real_count"));
			detail.setAcceptPrice(map.getDouble("real_price"));
			detail.setBranchRemark(map.getString("remark"));
			branchPurchaseOrderDetailService.update(detail);
		}

	}

	@Override
	public void saveOrderForZicai(Long id,Long merchantGroupId) {
		if (merchantGroupId==null){
			log.info("商户组不存在");
			return;
		}

		QyMap orderData = QyMap.WRAP(branchOrderService.getOrderData(id));
		List<Map<String,Object>> detailData = branchOrderService.getOrderDetailData(id);
		Branch branch = branchService.getBranchByMerchantId(orderData.getLong("merchant_id"),merchantGroupId);
		if (branch==null){
			throw new BusinessRunTimeException("门店不存在",10001);
		}
		//保存订单信息
		BranchPurchaseOrder order = new BranchPurchaseOrder();
		order.setState(BranchPurchaseState.NOAUDIT);
		order.setType(BranchPurchaseType.ZICAI);
		order.setSupplierName(orderData.getString("supplier_name"));
		order.setSupplierId(orderData.getLong("supplier_id"));
		order.setRemark(orderData.getString("remark"));
		order.setAmount(orderData.getDouble("amount"));
		order.setPurchaseTime(orderData.getTime("purchase_time"));
		order.setPurchaser(orderData.getString("purchaser"));
		order.setMerchantGroupId(merchantGroupId);
		order.setBranchName(branch.getName());
		order.setBranchId(branch.getId());
		order.setAddress(orderData.getString("address"));
		order.setNo(orderData.getString("no"));
		order.setWarehouseName(orderData.getString("warehouse_name"));
		order = this.save(order);

		//订单明细
		if (CollectionUtils.isEmpty(detailData)){
			throw new BusinessRunTimeException("订单明细为空",10001);
		}
		QyMap item;
		BranchPurchaseOrderDetail detail = null;
		for (Map<String, Object> data : detailData) {
			item = QyMap.WRAP(data);

			log.info("-------------details : {} : ",item);

			detail = new BranchPurchaseOrderDetail();
			detail.setBranchRemark(item.getString("remark"));
			detail.setSpecId(item.getLong("spec_id"));
			detail.setPurchaseUnit(item.getString("purchase_unit_name"));
			detail.setPurchaseSpec(item.getString("purchase_spec_name"));
			detail.setPurchasePrice(item.getDouble("price"));
			detail.setPurchaseCount(item.getDouble("count"));
			detail.setMaterialSpec(item.getString("spec"));
			detail.setName(item.getString("name"));
			detail.setNo(item.getString("no"));
			detail.setUuid(item.getString("uuid"));
			detail.setStockUnit(item.getString("unit"));
			detail.setOrder(order);
			log.info("-----------beizhu : {}",item.getString("remark"));
			detail.setMerchantGroupId(merchantGroupId);
			branchPurchaseOrderDetailService.save(detail);
		}

	}

	@Override
	public void deletedAll(Long id) {
		branchPurchaseOrderRepository.deleteDetail(id);
		this.delete(id);
	}

	@Override
	public void reject(String no, Long merchantGroupId) {
		//查询总部订单
		Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("no_eq",no);
		BranchPurchaseOrder order = this.findOne(searchable);
		if (order==null){
			throw new BusinessRunTimeException("订单不存在",10001);
		}
		//编辑单店的订单 状态修改为未审核
		branchOrderService.updateOrderState(no,order.getBranchId());
		//删除总部订单
		deletedAll(order.getId());


	}

	/**
	 * //减去库存 //出库单
	 * @param order
	 * @param detailList
	 */
	private void saveStoreOutOrder(BranchPurchaseOrder order,List<BranchPurchaseOrderDetail> detailList){
		//保存出库单据
		if (CollectionUtils.isEmpty(detailList)){
			return;
		}
//		PurchaseSpec purchaseSpec = null;
		StoreOutOrderDetail outOrderDetail = null;
		Stock stock = null;

		//根据属性分组
		Map<Long, List<BranchPurchaseOrderDetail>> listMap = detailList.stream().collect(Collectors.groupingBy(BranchPurchaseOrderDetail::getStockId));

		//去重根据某属性
		List<BranchPurchaseOrderDetail> unique = detailList.stream().collect(
				collectingAndThen(
						toCollection(() -> new TreeSet<>(comparingLong(BranchPurchaseOrderDetail::getStockId))), ArrayList::new)
		);
		//获取某一属性
		List<Long> sids=unique.stream().map(BranchPurchaseOrderDetail::getStockId).collect(Collectors.toList());

		Warehouse warehouse = null;

		List<BranchPurchaseOrderDetail> details = null;
		List<StoreOutOrderDetail> outOrderDetails = null;
		Material material ;
		double sumAmount = 0.0;
		double amount = 0.0;

		List<Long> specIds = detailList.stream().map(BranchPurchaseOrderDetail::getSpecId).collect(Collectors.toList());
		//查询单店的所有采购规格
		List<Map<String,Object>> specList = branchDataService.getPurchaseSpecsforBranch(specIds);
		for (Long sid : sids) {
			sumAmount = 0.0;

			details = listMap.get(sid);
			warehouse = warehouseService.findById(sid);
			if(warehouse==null){
				throw new BusinessRunTimeException("仓库不存在",10001);
			}
			StoreOutOrder storeOutOrder = new StoreOutOrder();
			storeOutOrder.setMerchantGroupId(order.getMerchantGroupId());
			storeOutOrder.setRemark(order.getRemark());
			storeOutOrder.setCheckerName(order.getChecker());
			storeOutOrder.setOperatorName(order.getChecker());
			storeOutOrder.setWarehouseId(sid);
			storeOutOrder.setWarehouseName(warehouse.getName());
			storeOutOrder.setType(StoreOutType.FAHUOOUT);
			storeOutOrder.setState(StoreOutState.AUDIT);
			storeOutOrder.setOutTime(new Date());
			storeOutOrder.setSupplierId(order.getSupplierId());
			storeOutOrder.setSupplierName(order.getSupplierName());
			storeOutOrder.setNo(LocalUtils.getOrderNo());
			storeOutOrder = storeOutOrderService.save(storeOutOrder);
			outOrderDetails = Lists.newArrayList();
			for (BranchPurchaseOrderDetail detail:details){
				amount = 0.0;
				outOrderDetail = new StoreOutOrderDetail();
				outOrderDetail.setMerchantGroupId(order.getMerchantGroupId());
				outOrderDetail.setRemark(detail.getRemark());
				outOrderDetail.setUnit(detail.getStockUnit());
				material = materialService.getMaterialByUUid(detail.getUuid(),order.getMerchantGroupId());
				if (material==null){
					throw new BusinessRunTimeException("该原料不存在",10001);
				}
//				purchaseSpec = purchaseSpecService.findById(detail.getSpecId());
				stock = stockService.getStocks(detail.getStockId(),material.getId(),order.getMerchantGroupId());
				outOrderDetail.setSpec(detail.getMaterialSpec());
				outOrderDetail.setNo(detail.getNo());
				outOrderDetail.setOrder(storeOutOrder);
				QyMap map = specList.stream().map(QyMap::WRAP).filter(x->x.getLong("id")==detail.getSpecId()).findFirst().orElse(QyMap.NEW());
				outOrderDetail.setCount(detail.getSendCount()*map.getDouble("range1"));
				outOrderDetail.setName(detail.getName());
				outOrderDetail.setMaterialId(material.getId());
				outOrderDetail.setPrice(stock.getCost());
				outOrderDetail.setTotal(stock.getCost()*outOrderDetail.getCount());
				outOrderDetail = storeOutOrderDetailService.save(outOrderDetail);

				outOrderDetails.add(outOrderDetail);

				amount=stock.getCost()*outOrderDetail.getCount();

				sumAmount = CompuUtils.add(amount,sumAmount);
			}
			//发货金额 = 库存成本价*数量
			storeOutOrder.setAmount(sumAmount);
			storeOutOrder = storeOutOrderService.update(storeOutOrder);
			storeOutOrderService.updateStock(storeOutOrder,outOrderDetails);
		}



	}


}